package com.realdolmen.whiteyellowcross.appengine.datastore;

import static com.google.appengine.api.datastore.FetchOptions.Builder.withLimit;

import java.util.ArrayList;
import java.util.List;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.realdolmen.whiteyellowcross.datastore.PersonelDataStore;
import com.realdolmen.whiteyellowcross.model.Personel;

public class PersonelAppEngineDataStore implements PersonelDataStore {

	private DatastoreService datastoreService;
	private static PersonelAppEngineDataStore personelAppEngineDataStore;

	private PersonelAppEngineDataStore(DatastoreService datastoreService) {
		this.datastoreService = datastoreService;
	}

	public static PersonelDataStore getInstance(
			DatastoreService datastoreService) {
		if (personelAppEngineDataStore == null) {
			synchronized (PersonelAppEngineDataStore.class) {
				if (personelAppEngineDataStore == null) {
					personelAppEngineDataStore = new PersonelAppEngineDataStore(
							datastoreService);
				}

			}
		}
		return personelAppEngineDataStore;
	}

	@Override
	public void addPersonel(String name) {
		Entity personelEntity = new Entity(Personel.class.getCanonicalName());
		personelEntity.setProperty("name", name);
		datastoreService.put(personelEntity);
	}

	public DatastoreService getDatastoreService() {
		return datastoreService;
	}

	public void setDatastoreService(DatastoreService datastoreService) {
		this.datastoreService = datastoreService;
	}

	@Override
	public Personel getPersonel(String name) {
		Personel personel = null;
		Entity entity = getPersonelEntity(name);
		
		if (entity != null) {
			personel = transFormEntityToPersonel(entity);
		}
		
		return personel;
	}

	private Entity getPersonelEntity(String name) {
		Query query = new Query(Personel.class.getCanonicalName());
		Filter filter = new FilterPredicate("name", FilterOperator.EQUAL, name);
		query.setFilter(filter);
		PreparedQuery preparedQuery = datastoreService.prepare(query);
		Entity entity = preparedQuery.asSingleEntity();
		return entity;
	}

	@Override
	public void deletePerson(String name) {
		Entity entity = getPersonelEntity(name);
		datastoreService.delete(entity.getKey());
	}

	@Override
	public int getTotalPersonel() {
		Query query = new Query(Personel.class.getCanonicalName());
		PreparedQuery preparedQuery = datastoreService.prepare(query);
		return preparedQuery.countEntities(withLimit(100));
	}

	@Override
	public List<Personel> getPersonelList() {
		Query query = new Query(Personel.class.getCanonicalName());
		PreparedQuery preparedQuery = datastoreService.prepare(query);
		List<Entity> entityList = preparedQuery.asList(withLimit(100));
		List<Personel> personelList = new ArrayList<Personel>();
		for (Entity entity : entityList) {
			personelList.add(transFormEntityToPersonel(entity));
		}
		return personelList;
	}

	private Personel transFormEntityToPersonel(Entity entity) {
		Personel personel = null;
		if (entity != null) {
			personel = new Personel((String) entity.getProperty("name"));
			personel.setId(KeyFactory.keyToString(entity.getKey()));
		}
		return personel;
	}

}
